package cc.rengu.igas.cops.core.service.trans.payment;

import cc.rengu.igas.cops.common.constant.CopsParamConstant;
import cc.rengu.igas.cops.common.constant.CopsTreeNodeConstant;
import cc.rengu.igas.cops.common.enums.RespCodeEnum;
import cc.rengu.igas.cops.core.service.base.PayService;
import cc.rengu.igas.cops.facade.bean.ExtraParam;
import cc.rengu.igas.cops.facade.bean.OrderDetail;
import cc.rengu.igas.cops.facade.request.GenPayOrderRequest;
import cc.rengu.igas.cops.facade.response.GenPayOrderResponse;
import cc.rengu.igas.share.common.enums.SignTypeEnum;
import cc.rengu.igas.share.core.model.MchntInfo;
import cc.rengu.igas.share.core.model.UserInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.UserService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.igas.share.core.realize.impl.UserServiceImpl;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.dao.UserOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.UserOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.MchntOrderDetail;
import cc.rengu.oltp.service.common.entity.MchntOrderInfo;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.*;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.realize.OrderService;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.OrderServiceImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.*;
import cc.rengu.utility.base.TimeUtil;
import org.apache.commons.codec.binary.Base64;

import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 生成支付订单
 * Created by wangcheng on 2021/6/17
 */
public class CopsGenPayOrderService extends PayService {

    @Override
    protected Object bizBeforeCust() throws Exception {
        GenPayOrderRequest genPayOrderRequest = new GenPayOrderRequest();
        ConvertUtil.convertOutput(genPayOrderRequest);
        return genPayOrderRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String sysSeqNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM);

        GenPayOrderRequest genPayOrderRequest = (GenPayOrderRequest) request;
        BizResponse<GenPayOrderResponse> bizResponse = new BizResponse<>();
        GenPayOrderResponse genPayOrderResponse = new GenPayOrderResponse();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);

        /* Step1：客户端环境参数校验 */
        if (null == genPayOrderRequest.getClientEnvParam() || StringUtil.isEmptyOrNull(genPayOrderRequest.getClientEnvParam().getCashierType())) {
            rglog.error("未上送客户端环境参数信息!");
            throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
        }
        SysParamService sysParamService = new SysParamServiceImpl();
        String cashierType = genPayOrderRequest.getClientEnvParam().getCashierType().equals(CopsParamConstant.OPMS_H5) ? CopsParamConstant.CASHIER_H5_URL : CopsParamConstant.CASHIER_WEB_URL;
        SysParam sysParam = sysParamService.getSysParamInfo(instId, CopsParamConstant.OPMS_SYS_PARAM, cashierType);
        if (null == sysParam) {
            rglog.info("法人行域名未配置<{}>收银台URL参数，instId:<{}>", genPayOrderRequest.getClientEnvParam().getCashierType(), instId);
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        }
        String onlineCasherUrl = sysParam.getParamValue().trim() + (cashierType.equals(CopsParamConstant.CASHIER_H5_URL) ? CopsParamConstant.URL_OPMS_F5 : CopsParamConstant.URL_OPMS_WEB);

        /* Step2: 附加参数处理 */
        List<ExtraParam> senitiveParamList = new ArrayList<>();
        List<ExtraParam> noEncParamList = new ArrayList<>();
        String userId = genPayOrderRequest.getHeader().getInstId() + DateUtil.getCurrentDate() + sysSeqNum.substring(sysSeqNum.length() - 8);
        List<ExtraParam> extraParamList = genPayOrderRequest.getExtraParamList();
        if (null != extraParamList && !extraParamList.isEmpty()) {
            /* Step2.1: 银行级签约根据证件信息先判断是否已存在用户，若存在，则用户标识就用系统已存在的用户标识 */
            if (platMchntInfo.getSignType().equals(SignTypeEnum.BANK_CLASS_SIGN.getSignTypeCode())) {
                Optional<ExtraParam> certTypeParamOpt = extraParamList.stream().filter(item -> item.getParamKey().equals("certType")).findFirst();
                Optional<ExtraParam> certNoParamOpt = extraParamList.stream().filter(item -> item.getParamKey().equals("certNo")).findFirst();
                if (certTypeParamOpt.isPresent() && certNoParamOpt.isPresent()) {
                    UserService userService = new UserServiceImpl();
                    String userInst = instId;
                    if (null != platMchntInfo && SignTypeEnum.PLAT_CLASS_SIGN.getSignTypeCode().equals(platMchntInfo.getSignType())) {
                        userInst = platMchntInfo.getPlatMchntNo();
                    }
                    String certType = certTypeParamOpt.get().getParamValue();
                    String certNo = certNoParamOpt.get().getParamValue();
                    UserInfo userInfo = userService.getUserInfoByCertInfo(instId, userInst, certType, certNo);
                    userId = (null == userInfo) ? userId : userInfo.getUserId();
                }
            }
            /* Step2.2: 基于附加参数分离敏感信息参数和非敏感信息参数 */
            extraParamList = filterParamNotPage(instId, extraParamList);
            Map<String, List<ExtraParam>> sensitiveMap = extraParamList.stream().collect(Collectors.groupingBy(ExtraParam::getSensitiveInfoFlag));
            if (sensitiveMap.get(AppParamConstant.YES) != null) {
                senitiveParamList = sensitiveMap.get(AppParamConstant.YES);
            }
            if (sensitiveMap.get(AppParamConstant.NO) != null) {
                noEncParamList = sensitiveMap.get(AppParamConstant.NO);
            }
        }

        /* Step3：生成订单信息 */
        OrderService orderService = new OrderServiceImpl();
        String userOrderId = orderService.generateUserOrderId();
        /* Step3.1：验证订单是否已经存在(同一渠道的商户订单号唯一) */
        UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();
        UserOrderInfo existsUserOrderInfo = userOrderInfoMapper.selectUserOrderInfoByMchntOrderId(instId,
                genPayOrderRequest.getMchntOrderId(), genPayOrderRequest.getHeader().getSrcSysId(), genPayOrderRequest.getHeader().getChanlId());
        if (null != existsUserOrderInfo) {
            rglog.info("该订单已经存在，mchntOrderId:<{}>", genPayOrderRequest.getMchntOrderId());
            genPayOrderResponse.setOrderStatus(existsUserOrderInfo.getOrderStatus());
            bizResponse.setResult(genPayOrderResponse);
            bizResponse.setRespCode(RespCodeEnum.ORDER_ALREADY_EXISTS.getRespCode());
            bizResponse.setRespDesc(RespCodeEnum.ORDER_ALREADY_EXISTS.getRespDesc());
            return bizResponse;
        }
        /* Step3.2：生成用户订单及商户订单信息 */
        List<OrderDetail> orderDetails = genPayOrderRequest.getOrderDetailList();
        UserOrderInfo userOrderInfo = generateUserOrderInfo(genPayOrderRequest, userOrderId);
        List<MchntOrderInfo> mchntOrderInfos = generateMchntOrderInfo(orderDetails, genPayOrderRequest);
        List<MchntOrderDetail> mchntOrderDetails = null;
        /* Step3.2.1：担保支付和购买卡券的交易登记商户订单详情表 */
        if ("01".equals(genPayOrderRequest.getBizSceneType()) || "02".equals(genPayOrderRequest.getBizSceneType()) || "03".equals(genPayOrderRequest.getBizSceneType())) {
            rglog.info("担保支付和购买卡券的交易登记商户订单详情表，orderDetails:<{}>", orderDetails);
            mchntOrderDetails = generateMchntOrderDetail(orderDetails, genPayOrderRequest);
        }
        if (!orderService.registerOrderInfo(userOrderInfo, mchntOrderInfos, mchntOrderDetails, null)) {
            throw new BizException(RespCodeEnum.INSERT_PAY_ORDER_ERROR.getRespCode(), RespCodeEnum.INSERT_PAY_ORDER_ERROR.getRespDesc());
        }
        /* Step4：组装收银台跳转地址 */
        SysParam aesKeyParam = sysParamService.getSysParamInfo(AppParamConstant.DEFAULT_INSTID, CopsParamConstant.OPMS_SYS_PARAM, CopsParamConstant.AES_ENC_KEY);
        if (null == aesKeyParam) {
            rglog.info("AES密钥未配置");
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        }
        /* Step4.1：将用户标识、用户订单号加到敏感参数信息中 */
        ExtraParam userIdParam = new ExtraParam(TreeNodeConstant.USER_ID, userId);
        senitiveParamList.add(userIdParam);
        ExtraParam userOrderIdParam = new ExtraParam(TreeNodeConstant.USER_ORDER_ID, userOrderId);
        senitiveParamList.add(userOrderIdParam);
        /* Step4.2：将平台商户号加到非敏感参数信息中 */
        ExtraParam platMchntNoParam = new ExtraParam(TreeNodeConstant.PLAT_MCHNT_NO, platMchntInfo.getPlatMchntNo());
        noEncParamList.add(platMchntNoParam);
        String onlineCasherUrlStr = generateCashierUrl(onlineCasherUrl, aesKeyParam.getParamValue(), senitiveParamList, noEncParamList);

        /* Step5： 返回应答信息 */
        genPayOrderResponse.setOrderStatus(OrderStatusEnum.INIT.getStatus());
        genPayOrderResponse.setUserOrderId(userOrderId);
        genPayOrderResponse.setOnlineCasherUrl(onlineCasherUrlStr);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(genPayOrderResponse);
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        GenPayOrderResponse genPayOrderResponse = (GenPayOrderResponse) bizResponse.getResult();
        ConvertUtil.convertInput(genPayOrderResponse);
    }

    /**
     * 根据配置拼装收银台URL地址
     *
     * @param transUrl URL地址
     * @return URL地址
     */
    private String generateCashierUrl(String transUrl, String aesKey, List<ExtraParam> senitiveParamList, List<ExtraParam> noEncParamList) throws Exception {
        StringBuilder requestUrlParam = new StringBuilder();
        StringBuilder encryptDataParam = new StringBuilder();
        if (senitiveParamList.size() != 0) {
            for (ExtraParam extraParam : senitiveParamList) {
                encryptDataParam.append(extraParam.getParamKey()).append("=").append(extraParam.getParamValue()).append("&");
            }
            String encryptData = AESUtil.pkcs7CbcEncryptData(Base64.decodeBase64(aesKey), encryptDataParam.substring(0, encryptDataParam.length() - 1).getBytes());
            requestUrlParam.append(CopsTreeNodeConstant.ENCRYPT_DATA + "=").append(URLEncoder.encode(encryptData, "UTF-8")).append("&");
        }
        if (noEncParamList.size() != 0) {
            for (ExtraParam extraParam : noEncParamList) {
                requestUrlParam.append(extraParam.getParamKey()).append("=").append(extraParam.getParamValue()).append("&");
            }
        }
        return transUrl + requestUrlParam.substring(0, requestUrlParam.length() - 1);
    }

    /**
     * 删除非页面参数
     *
     * @param instId      多法人标识
     * @param extraParams 交易请求附加参数
     * @return 收银台URL附加参数列表
     * @throws Exception 异常
     */
    private List<ExtraParam> filterParamNotPage(String instId, List<ExtraParam> extraParams) throws Exception {
        List<ExtraParam> extraParamList = new ArrayList<>(Arrays.asList(new ExtraParam[extraParams.size()]));
        Collections.copy(extraParamList, extraParams);
        /*获取需要过滤的参数*/
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(instId, CopsParamConstant.OPMS_SYS_PARAM, CopsParamConstant.NOT_PAGE_PARAM);
        if (null != sysParam && !StringUtil.isEmptyOrNull(sysParam.getParamValue()) && extraParams.size() != 0) {
            for (ExtraParam extraParam : extraParams) {
                if (Arrays.asList(sysParam.getParamValue().split(",")).contains(extraParam.getParamKey())) {
                    extraParamList.remove(extraParam);
                }
            }
        }
        return extraParamList;
    }

    /**
     * 生成用户订单信息
     *
     * @param request 请求实体
     * @return 用户订单实体
     * @throws Exception 异常
     */
    private UserOrderInfo generateUserOrderInfo(GenPayOrderRequest request, String userOrderId) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        UserOrderInfo userOrderInfo = new UserOrderInfo();
        BeanUtil.beanCopy(request.getHeader(), userOrderInfo);
        userOrderInfo.setTxnNum(request.getHeader().getTxnNum());
        userOrderInfo.setTxnDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_DATE));
        userOrderInfo.setTxnTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_TIME));
        userOrderInfo.setMsgSrcId(request.getHeader().getSrcSysId());
        userOrderInfo.setTransChannelId(request.getHeader().getChanlId());
        userOrderInfo.setUserOrderId(userOrderId);
        userOrderInfo.setMchntOrderId(request.getMchntOrderId());
        userOrderInfo.setOrderDesc(request.getOrderDesc());
        userOrderInfo.setUserId(request.getUserId());
        userOrderInfo.setOrderCcy(request.getOrderCcy());
        userOrderInfo.setOrderAmt(request.getOrderAmt());
        userOrderInfo.setNeedPayAmt(AmountUtil.subtraction(request.getOrderAmt(), StringUtil.isEmptyOrNull(request.getRealDiscountAmt()) ? CopsParamConstant.STR_ZERO : request.getRealDiscountAmt()));
        userOrderInfo.setRealPayAmt(AmountUtil.subtraction(request.getOrderAmt(), StringUtil.isEmptyOrNull(request.getRealDiscountAmt()) ? CopsParamConstant.STR_ZERO : request.getRealDiscountAmt()));
        userOrderInfo.setRealDiscountAmt(request.getRealDiscountAmt());
        userOrderInfo.setFrontSeqNum(request.getHeader().getTraceNo());
        userOrderInfo.setFrontBackUrl(request.getFrontBackUrl());
        userOrderInfo.setNotifyBackUrl(request.getNotifyBackUrl());
        userOrderInfo.setSysSeqNum(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM));
        String orderCreateTime = DateUtil.getCurrentDateTime("yyyyMMddHHmmss");
        userOrderInfo.setOrderCreateTime(orderCreateTime);
        userOrderInfo.setOrderExpiryTime(getOrderExpiryTime(request.getHeader().getInstId(), request.getOrderExpiryTime(), orderCreateTime));
        userOrderInfo.setOrderStatus(OrderStatusEnum.INIT.getStatus());
        userOrderInfo.setTransStatus(TransStatusEnum.TRANS_INIT.getStatus());
        userOrderInfo.setBizStatus(BizStatusEnum.INIT.getStatus());
        userOrderInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
        userOrderInfo.setGroupMchntNo(platMchntInfo.getPlatMchntNo());
        userOrderInfo.setGroupMchntName(platMchntInfo.getPlatMchntName());
        return userOrderInfo;
    }

    /**
     * 计算订单有效期
     *
     * @param instId           机构号
     * @param orderExprityTime 上传的订单有效期
     * @param orderCreateTime  订单创建时间
     * @return 订单有效期 yyyyMMddhhmmss
     * @throws Exception 异常
     */
    private String getOrderExpiryTime(String instId, String orderExprityTime, String orderCreateTime) throws Exception {
        String exprityTime;
        if (StringUtil.isEmptyOrNull(orderExprityTime)) {
            SysParamService sysParamService = new SysParamServiceImpl();
            SysParam sysParamInfo = sysParamService.getSysParamInfo(instId, CopsParamConstant.OPMS_SYS_PARAM, CopsParamConstant.ORDER_EXPIRY_TIME);
            exprityTime = sysParamInfo == null || StringUtil.isEmptyOrNull(sysParamInfo.getParamValue()) ? CopsParamConstant.ORDER_DEFAULT_EXPIRY_TIME : sysParamInfo.getParamValue();
        } else {
            exprityTime = orderExprityTime;
        }
        return TimeUtil.calcDays(orderCreateTime, Long.parseLong(exprityTime));
    }

    /**
     * 根据订单明细创建商户订单
     *
     * @param orderDetails       订单明细
     * @param genPayOrderRequest 请求体
     * @return 商户订单
     * @throws Exception 异常
     */
    private List<MchntOrderInfo> generateMchntOrderInfo(List<OrderDetail> orderDetails, GenPayOrderRequest genPayOrderRequest) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        List<MchntOrderInfo> mchntOrderList = new ArrayList<>();
        String instId = genPayOrderRequest.getHeader().getInstId();
        String transAmt = genPayOrderRequest.getOrderAmt();
        String totalOrderAmt = "0";
        String totalDiscAmt = "0";
        String totalRealSettleAmt = "0";
        /* 按商户分组去重，累计求和 */
        Map<String, List<OrderDetail>> groupByMchntNo = orderDetails.stream().collect(Collectors.groupingBy(OrderDetail::getMchntNo));
        MchntOrderInfo mchntOrderInfo;
        for (Map.Entry<String, List<OrderDetail>> entryMchntNo : groupByMchntNo.entrySet()) {
            String totalMchntOrderAmt = "0";
            String totalMchntDiscAmt = "0";
            String totalMchntRealSettleAmt = "0";
            String mchntNo = entryMchntNo.getKey();
            List<OrderDetail> entryMchtDetailList = entryMchntNo.getValue();
            for (OrderDetail mchntDetail : entryMchtDetailList) {
                /* 订单金额累计 */
                totalMchntOrderAmt = AmountUtil.addition(totalMchntOrderAmt, mchntDetail.getOrderAmt());
                /* 订单优惠金额累计 */
                totalMchntDiscAmt = AmountUtil.addition(totalMchntDiscAmt, mchntDetail.getOrderDiscountAmt());
                /* 商户结算金额 */
                totalMchntRealSettleAmt = AmountUtil.addition(totalMchntRealSettleAmt, mchntDetail.getOrderSettleAmt());
            }
            MchntService mchntService = new MchntServiceImpl();
            MchntInfo mchntInfo = mchntService.getMchntInfo(instId, mchntNo);
            if (null == mchntInfo) {
                rglog.info("商户不存在或商户状态异常，instId:<{}>,mchntNo:<{}>", instId, mchntNo);
                throw new BizException(RespCodeEnum.MCHNT_INVALID.getRespCode(), RespCodeEnum.MCHNT_INVALID.getRespDesc());
            }
            /* 商户有所属的平台商户则校验上送的平台商户是否与基本商户所属的平台商户是否一致 */
            if (!StringUtil.isEmptyOrNull(mchntInfo.getPlatMchntNo()) && !genPayOrderRequest.getPlatMchntNo().equals(mchntInfo.getPlatMchntNo())) {
                rglog.info("商户信息不一致,上送商户号:<{}>,订单明细商户号:<{}>,订单明细商户所属平台商户:<{}>", genPayOrderRequest.getPlatMchntNo(), mchntNo, mchntInfo.getPlatMchntNo());
                throw new BizException(RespCodeEnum.MCHNT_DISACCORD.getRespCode(), RespCodeEnum.MCHNT_DISACCORD.getRespDesc());
            }
            /* 商户限额检查 */
            int checkResult = mchntService.checkMchntTransLimit(instId, totalMchntRealSettleAmt, LimitAcctTypeEnum.ALL, mchntNo, null, "T01CP000");
            if (0 != checkResult) {
                rglog.error("商户<{}>交易限额超限!", mchntNo);
                throw new BizException(RespCodeEnum.MCHNT_AMT_OVER.getRespCode(), RespCodeEnum.MCHNT_AMT_OVER.getRespDesc());
            }
            mchntOrderInfo = new MchntOrderInfo();
            mchntOrderInfo.setInstId(genPayOrderRequest.getHeader().getInstId());
            mchntOrderInfo.setTxnDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_DATE));
            mchntOrderInfo.setTxnTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_TIME));
            mchntOrderInfo.setTxnNum(genPayOrderRequest.getHeader().getTxnNum());
            mchntOrderInfo.setBizType(genPayOrderRequest.getHeader().getBizType());
            mchntOrderInfo.setBizProdCode(BaseProdEnum.BASIC.getProdCode());
            mchntOrderInfo.setBizSceneType(genPayOrderRequest.getBizSceneType());
            mchntOrderInfo.setSysSeqNum(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM));
            mchntOrderInfo.setMchntOrderId(genPayOrderRequest.getMchntOrderId());
            mchntOrderInfo.setOrderDesc(entryMchtDetailList.get(0).getMchntOrderDesc());
            mchntOrderInfo.setAcqInstCode(mchntInfo.getSignInstId());
            mchntOrderInfo.setIndustryType(mchntInfo.getIndustryType());
            mchntOrderInfo.setMchntNo(mchntNo);
            mchntOrderInfo.setMchntName(mchntInfo.getMchntName());
            mchntOrderInfo.setOrderCcy(entryMchtDetailList.get(0).getOrderCcy());
            mchntOrderInfo.setOrderAmt(totalMchntOrderAmt);
            mchntOrderInfo.setOrderDiscountAmt(totalMchntDiscAmt);
            mchntOrderInfo.setRealSettleAmt(totalMchntRealSettleAmt);
            mchntOrderInfo.setRealSettleFlag(mchntInfo.getRealSettleFlag());
            mchntOrderInfo.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            mchntOrderInfo.setChainMchntNo(mchntInfo.getChainMchntNo());
            mchntOrderList.add(mchntOrderInfo);
            totalOrderAmt = AmountUtil.addition(totalOrderAmt, totalMchntOrderAmt);
            totalDiscAmt = AmountUtil.addition(totalDiscAmt, totalMchntDiscAmt);
            totalRealSettleAmt = AmountUtil.addition(totalRealSettleAmt, totalMchntRealSettleAmt);
        }

        /*判断订单明细总金额跟总金额是否一致*/
        if (AmountUtil.compare(transAmt, totalOrderAmt) != 0) {
            rglog.error("订单明细总金额<{}>跟订单总金额<{}>不一致", totalOrderAmt, transAmt);
            throw new BizException(RespCodeEnum.TRANS_AMT_DISACCORD.getRespCode(), RespCodeEnum.TRANS_AMT_DISACCORD.getRespDesc());
        }
        if (AmountUtil.compare(genPayOrderRequest.getRealDiscountAmt(), totalDiscAmt) != 0) {
            rglog.error("订单明细总金额<{}>跟订单总金额<{}>不一致", totalDiscAmt, genPayOrderRequest.getRealDiscountAmt());
            throw new BizException(RespCodeEnum.TRANS_AMT_DISACCORD.getRespCode(), RespCodeEnum.TRANS_AMT_DISACCORD.getRespDesc());
        }
        return mchntOrderList;
    }

    /**
     * 根据订单明细创建商户订单明细
     *
     * @param orderDetails       订单明细
     * @param genPayOrderRequest 请求体
     * @return 商户订单
     * @throws Exception 异常
     */
    private List<MchntOrderDetail> generateMchntOrderDetail(List<OrderDetail> orderDetails, GenPayOrderRequest genPayOrderRequest) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        List<MchntOrderDetail> mchntOrderList = new ArrayList<>();
        MchntOrderDetail mchntOrderDetail;
        for (OrderDetail orderDetail : orderDetails) {
            mchntOrderDetail = new MchntOrderDetail();
            mchntOrderDetail.setInstId(genPayOrderRequest.getHeader().getInstId());
            mchntOrderDetail.setTxnDate(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_DATE));
            mchntOrderDetail.setTxnTime(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_TIME));
            mchntOrderDetail.setMchntNo(orderDetail.getMchntNo());
            mchntOrderDetail.setMchntOrderId(genPayOrderRequest.getMchntOrderId());
            mchntOrderDetail.setMchntSubOrderId(orderDetail.getMchntSubOrderId());
            mchntOrderDetail.setSysSeqNum(xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SYS_SEQ_NUM));
            mchntOrderDetail.setMchntOrderDesc(orderDetail.getMchntOrderDesc());
            mchntOrderDetail.setMchntOrderType(orderDetail.getMchntOrderType());
            mchntOrderDetail.setOrderAmt(orderDetail.getOrderAmt());
            mchntOrderDetail.setOrderDiscountAmt(orderDetail.getOrderDiscountAmt());
            mchntOrderDetail.setRealSettleAmt(orderDetail.getOrderSettleAmt());
            mchntOrderDetail.setCreateTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            mchntOrderList.add(mchntOrderDetail);
        }
        return mchntOrderList;
    }
}
